package 网络编程;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
 * 服务端
 *DatagramSocket  socker可以理解为送快递的
 * DatagramPacket 可以理解为包裹
 */
public class UdpEchoClient {
    DatagramSocket socket=null;
    //port为端口号
    public UdpEchoClient(int port) throws SocketException {
       socket=new DatagramSocket(port);
    }
    public void start() throws IOException {
        //服务器一般都是不间断运行的
        while (true){
            /**
             * 第一步获取请求
             */
            //读取请求，当前服务器不知道客户端什么时间发送请求，receive方法会堵塞
            //如果有请求发送过来了，此时receive就会返回
            //参数Datagrampacket是一个输出性的参数,它在构造时需要指定一个缓冲区
            DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4093);
            //返回值为void，但是是把值放入参数中，用参数返回，这样做的原因是想让用户指定一个缓冲区
            socket.receive(requestPacket);
            //把请求取出来放入字符串中，这样后面好处理
            String receive=new String(requestPacket.getData(),0,requestPacket.getLength());
            /**
             * 第二步根据请求来计算响应
             */
            String response=process(receive);
            /**
             * 第三步把响应写回到客户端
             */
            //最后一个参数为发出请求的ip和端口
            DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,
                                                            requestPacket.getSocketAddress());
            socket.send(responsePacket);
            /**
             * 第四步打印日志
             */
            String log=String.format("[%s,%d], req:%s,resp:%s",
                                    requestPacket.getAddress().toString(),//客户端的端口和ip
                                    requestPacket.getPort(),
                                    receive,response
                                    );
            System.out.println(log);
        }
    }
    //因为是个回显服务器所以把客户端发的请求返回即可
    private String process(String s){
        return s;
    }

    public static void main(String[] args) throws IOException {
        UdpEchoClient client=new UdpEchoClient(9090);
        System.out.println("服务器启动成功");
        client.start();
    }
}
